return NULL;
}
+/**
+ * gtk_cell_area_copy_context:
+ * @area: a #GtkCellArea
+ * @context: the #GtkCellAreaContext to copy
+ *
+ * This is sometimes needed for cases where rows need to share
+ * alignments in one orientation but may be separately grouped
+ * in the opposing orientation.
+ *
+ * For instance, #GtkIconView creates all icons (rows) to have
+ * the same width and the cells theirin to have the same
+ * horizontal alignments. However each row of icons may have
+ * a separate collective height. #GtkIconView uses this to
+ * request the heights of each row based on a context which
+ * was already used to request all the row widths that are
+ * to be displayed.
+ *
+ * Return value: (transfer full): a newly created #GtkCellAreaContext copy of @context.
+ *
+ * Since: 3.0
+ */
+GtkCellAreaContext *
+gtk_cell_area_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context)
+{
+ GtkCellAreaClass *class;
+
+ g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
+ g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
+
+ class = GTK_CELL_AREA_GET_CLASS (area);
+
+ if (class->copy_context)
+ return class->copy_context (area, context);
+
+ g_warning ("GtkCellAreaClass::copy_context not implemented for `%s'",
+ g_type_name (G_TYPE_FROM_INSTANCE (area)));
+
+ return NULL;
+}
/**
* gtk_cell_area_get_request_mode:
/* Geometry */
GtkCellAreaContext *(* create_context) (GtkCellArea *area);
+ GtkCellAreaContext *(* copy_context) (GtkCellArea *area,
+ GtkCellAreaContext *context);
GtkSizeRequestMode (* get_request_mode) (GtkCellArea *area);
void (* get_preferred_width) (GtkCellArea *area,
GtkCellAreaContext *context,
/* Geometry */
GtkCellAreaContext *gtk_cell_area_create_context (GtkCellArea *area);
+GtkCellAreaContext *gtk_cell_area_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context);
GtkSizeRequestMode gtk_cell_area_get_request_mode (GtkCellArea *area);
void gtk_cell_area_get_preferred_width (GtkCellArea *area,
GtkCellAreaContext *context,
GValue *value,
GParamSpec *pspec);
static GtkCellAreaContext *gtk_cell_area_box_create_context (GtkCellArea *area);
+static GtkCellAreaContext *gtk_cell_area_box_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context);
static GtkSizeRequestMode gtk_cell_area_box_get_request_mode (GtkCellArea *area);
static void gtk_cell_area_box_get_preferred_width (GtkCellArea *area,
GtkCellAreaContext *context,
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
area_class->create_context = gtk_cell_area_box_create_context;
+ area_class->copy_context = gtk_cell_area_box_copy_context;
area_class->get_request_mode = gtk_cell_area_box_get_request_mode;
area_class->get_preferred_width = gtk_cell_area_box_get_preferred_width;
area_class->get_preferred_height = gtk_cell_area_box_get_preferred_height;
return context;
}
+static GtkCellAreaContext *
+gtk_cell_area_box_copy_context (GtkCellArea *area,
+ GtkCellAreaContext *context)
+{
+ GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
+ GtkCellAreaBoxPrivate *priv = box->priv;
+ GtkCellAreaContext *copy =
+ (GtkCellAreaContext *)gtk_cell_area_box_context_copy (GTK_CELL_AREA_BOX (area),
+ GTK_CELL_AREA_BOX_CONTEXT (context));
+
+ priv->contexts = g_slist_prepend (priv->contexts, copy);
+
+ g_object_weak_ref (G_OBJECT (copy), (GWeakNotify)context_weak_notify, box);
+
+ return copy;
+}
+
static GtkSizeRequestMode
gtk_cell_area_box_get_request_mode (GtkCellArea *area)
{
static void gtk_cell_area_box_context_allocate (GtkCellAreaContext *context,
gint width,
gint height);
+static void gtk_cell_area_box_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+static void gtk_cell_area_box_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
+
+
/* Internal functions */
-static void gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
- GtkOrientation orientation);
+static void gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size);
static void free_cache_array (GArray *array);
static GArray *group_array_new (GtkCellAreaBoxContext *context);
static GArray *get_array (GtkCellAreaBoxContext *context,
/* GObjectClass */
object_class->finalize = gtk_cell_area_box_context_finalize;
- context_class->reset = gtk_cell_area_box_context_reset;
- context_class->allocate = gtk_cell_area_box_context_allocate;
+ context_class->reset = gtk_cell_area_box_context_reset;
+ context_class->allocate = gtk_cell_area_box_context_allocate;
+ context_class->get_preferred_height_for_width = gtk_cell_area_box_context_get_preferred_height_for_width;
+ context_class->get_preferred_width_for_height = gtk_cell_area_box_context_get_preferred_width_for_height;
g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxContextPrivate));
}
static void
gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
- GtkOrientation orientation)
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
{
GtkCellArea *area;
GtkOrientation box_orientation;
area = gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (context));
spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
box_orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
- array = get_array (context, orientation, -1);
+ array = get_array (context, orientation, for_size);
for (i = 0; i < array->len; i++)
{
}
}
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_cell_area_context_push_preferred_width (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
- else
- gtk_cell_area_context_push_preferred_height (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
+ if (for_size < 0)
+ {
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ gtk_cell_area_context_push_preferred_width (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
+ else
+ gtk_cell_area_context_push_preferred_height (GTK_CELL_AREA_CONTEXT (context), min_size, nat_size);
+ }
+
+ if (minimum_size)
+ *minimum_size = min_size;
+ if (natural_size)
+ *natural_size = nat_size;
+}
+
+static void
+gtk_cell_area_box_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ gtk_cell_area_box_context_sum (GTK_CELL_AREA_BOX_CONTEXT (context), GTK_ORIENTATION_VERTICAL,
+ width, minimum_height, natural_height);
+}
+
+static void
+gtk_cell_area_box_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ gtk_cell_area_box_context_sum (GTK_CELL_AREA_BOX_CONTEXT (context), GTK_ORIENTATION_HORIZONTAL,
+ height, minimum_width, natural_width);
}
/*************************************************************
* API *
*************************************************************/
+static void
+copy_size_array (GArray *src_array,
+ GArray *dest_array)
+{
+ gint i;
+
+ for (i = 0; i < src_array->len; i++)
+ {
+ CachedSize *src = &g_array_index (src_array, CachedSize, i);
+ CachedSize *dest = &g_array_index (dest_array, CachedSize, i);
+
+ memcpy (dest, src, sizeof (CachedSize));
+ }
+}
+
+static void
+for_size_copy (gpointer key,
+ GArray *size_array,
+ GHashTable *dest_hash)
+{
+ GArray *new_array;
+
+ new_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
+ g_array_set_size (new_array, size_array->len);
+
+ copy_size_array (size_array, new_array);
+
+ g_hash_table_insert (dest_hash, key, new_array);
+}
+
+GtkCellAreaBoxContext *
+gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *box_context)
+{
+ GtkCellAreaBoxContext *context;
+
+ context = g_object_new (GTK_TYPE_CELL_AREA_BOX_CONTEXT,
+ "area", box, NULL);
+
+ gtk_cell_area_box_init_groups (context,
+ box_context->priv->base_widths->len,
+ box_context->priv->expand);
+
+ /* Copy all the arrays */
+ copy_size_array (box_context->priv->base_widths,
+ context->priv->base_widths);
+ copy_size_array (box_context->priv->base_heights,
+ context->priv->base_heights);
+
+ g_hash_table_foreach (box_context->priv->heights,
+ (GHFunc)for_size_copy, context->priv->heights);
+ g_hash_table_foreach (box_context->priv->widths,
+ (GHFunc)for_size_copy, context->priv->widths);
+
+ return context;
+}
+
void
gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
guint n_groups,
}
if (grew)
- gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_HORIZONTAL);
+ gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_HORIZONTAL, -1, NULL, NULL);
}
void
}
if (grew)
- gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_VERTICAL);
+ gtk_cell_area_box_context_sum (box_context, GTK_ORIENTATION_VERTICAL, -1, NULL, NULL);
}
void
GType gtk_cell_area_box_context_get_type (void) G_GNUC_CONST;
+/* Create a duplicate of the context */
+GtkCellAreaBoxContext *gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
+ GtkCellAreaBoxContext *box_context);
+
/* Initialize group array dimensions */
void gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
guint n_groups,
*natural_height = priv->nat_height;
}
+/**
+ * gtk_cell_area_context_get_preferred_height_for_width:
+ * @context: a #GtkCellAreaContext
+ * @width: a proposed width for allocation
+ * @minimum_height: (out) (allow-none): location to store the minimum height, or %NULL
+ * @natural_height: (out) (allow-none): location to store the natural height, or %NULL
+ *
+ * Gets the accumulative preferred height for @width for all rows which have been
+ * requested for the same said @width with this context.
+ *
+ * After gtk_cell_area_context_reset() is called and/or before ever requesting
+ * the size of a #GtkCellArea, the returned values are -1.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ if (GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_height_for_width)
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_height_for_width (context,
+ width,
+ minimum_height,
+ natural_height);
+}
+
+/**
+ * gtk_cell_area_context_get_preferred_width_for_height:
+ * @context: a #GtkCellAreaContext
+ * @height: a proposed height for allocation
+ * @minimum_width: (out) (allow-none): location to store the minimum width, or %NULL
+ * @natural_width: (out) (allow-none): location to store the natural width, or %NULL
+ *
+ * Gets the accumulative preferred width for @height for all rows which have
+ * been requested for the same said @height with this context.
+ *
+ * After gtk_cell_area_context_reset() is called and/or before ever requesting
+ * the size of a #GtkCellArea, the returned values are -1.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+
+ if (GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_width_for_height)
+ GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_width_for_height (context,
+ height,
+ minimum_width,
+ natural_width);
+}
+
/**
* gtk_cell_area_context_get_allocation:
* @context: a #GtkCellAreaContext
GObjectClass parent_class;
/*< public >*/
- void (* allocate) (GtkCellAreaContext *context,
- gint width,
- gint height);
- void (* reset) (GtkCellAreaContext *context);
+ void (* allocate) (GtkCellAreaContext *context,
+ gint width,
+ gint height);
+ void (* reset) (GtkCellAreaContext *context);
+ void (* get_preferred_height_for_width) (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+ void (* get_preferred_width_for_height) (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
/*< private >*/
/* Padding for future expansion */
GType gtk_cell_area_context_get_type (void) G_GNUC_CONST;
/* Main apis */
-GtkCellArea *gtk_cell_area_context_get_area (GtkCellAreaContext *context);
-void gtk_cell_area_context_allocate (GtkCellAreaContext *context,
- gint width,
- gint height);
-void gtk_cell_area_context_reset (GtkCellAreaContext *context);
+GtkCellArea *gtk_cell_area_context_get_area (GtkCellAreaContext *context);
+void gtk_cell_area_context_allocate (GtkCellAreaContext *context,
+ gint width,
+ gint height);
+void gtk_cell_area_context_reset (GtkCellAreaContext *context);
/* Apis for GtkCellArea clients to consult cached values for a series of GtkTreeModel rows */
-void gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
- gint *minimum_width,
- gint *natural_width);
-void gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
- gint *minimum_height,
- gint *natural_height);
-void gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
- gint *width,
- gint *height);
+void gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+void gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width);
+void gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
+ gint *width,
+ gint *height);
/* Apis for GtkCellArea implementations to update cached values for multiple GtkTreeModel rows */
void gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,